
#include "stdafx.h"
#include "layoutDesc.h"
#include "layoutHierarchyBuilder.h"

CLayoutHierarchyBuilder::~CLayoutHierarchyBuilder()
{
	for ( auto* ptr : m_groups )
		delete ptr;
}

bool CLayoutHierarchyBuilder::ReindexClasses( const CLayoutDefinition& layout )
{
	// cleanup
	for ( auto* ptr : m_groups )
		delete ptr;

	// add groups from layout and create dependencies between them
	for ( const CLayoutGroup* group : layout.GetGroups() )
		AddGroup( group );

	// reindex classes (index 0 is not allowed)
	int curIndex = 1;
	for ( auto* ptr : m_groups )
	{
		// process the child classes
		if ( ptr->m_group->GetBaseGroup() == nullptr )
		{
			WalkClassTree( ptr, curIndex );
		}
	}

	// done
	return true;
}

void CLayoutHierarchyBuilder::WalkClassTree( GroupInfo* group, int& index )
{
	group->m_group->m_classIndex = index;
	index++;

	for ( GroupInfo* child : group->m_children )
		WalkClassTree( child, index );

	group->m_group->m_lastChildIndex = index;
}

CLayoutHierarchyBuilder::GroupInfo* CLayoutHierarchyBuilder::GetWrapper( const CLayoutGroup* group )
{
	for ( auto* ptr : m_groups )
		if ( ptr->m_group == group )
			return ptr;

	auto* newPtr = new GroupInfo( (CLayoutGroup*) group );
	m_groups.push_back( newPtr );
	return newPtr;
}

void CLayoutHierarchyBuilder::AddGroup( const CLayoutGroup* group )
{
	auto* wrapper = GetWrapper( group );

	// register in parent group
	if ( group->GetBaseGroup() )
	{
		auto* parentWrapper = GetWrapper( group->GetBaseGroup() );
		parentWrapper->AddChildren( wrapper );
	}
}